fn main() {
    println!("引用, 借用");
    // 引用与 go 中引用的区别, rust中的引用变量, 没有所有权. 不能修改变量内容.
    let s1 = String::from("hello reference");
    let s2 = &s1;
    let s3 = &s1;
    println!("{},{}", s2, s3);

    let size = reference(s2);
    println!("{size}");

    // 可变引用 mut
    let mut s1 = String::from("mut string1");
    s1.push('c');
    let s2 = &mut s1;
    // s1.push('c'); // second mutable borrow occurs here
    // 可变引用只能有一个.创建多个时会报错
    // let s3 = &mut s1; // second mutable borrow occurs here
    let size = reference_mut(s2);
    println!("{size}");

    // 已出了 s2 的作用域 s1 所有权收回, 可再次可变引用了
    let s3 = &mut s1;
    let size = reference_mut(s3);
    // println!("s3: {} s1: {} {size}", s3, s1); // 提示 s1: immutable borrow occurs here
    println!("s1: {} {size}", s1);

    println!("在任意给定时间，要么 只能有一个可变引用，要么 只能有多个不可变引用。");
    println!("引用必须总是有效的")
}

fn reference(s: &String) -> usize {
    // consider changing this to be a mutable reference: `&mut String`
    // s.push_str("test"); // `s` is a `&` reference, so the data it refers to cannot be borrowed as mutable
    s.len()
}

fn reference_mut(s: &mut String) -> usize {
    s.push_str("mut string");
    s.len()
}
